package com.cy.pj.common.web;

import org.apache.shiro.ShiroException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import com.cy.pj.common.bo.JsonResult;

/**
 * 此类负责处理全局的异常
 * @ControllerAdvice 这个注解描述的类为springweb模块(MVC)中的控制层的一个全局异常处理对象
 * 当控制层出现异常以后,首先会检测控制层方法中是否有异常处理方法控制类中加(@ExceptionHandler)注解的异常处理方法
 * ,假如没有或者不能处理当前异常,则会查找是否有@ControllerAdvice描述的类
 * 如果有,然后检测全局异常处理类中是否有合适的异常处理方法,加入由则直接调用方法处理异常
 * 
 * 为什么要做全局异常处理?
 * 增加复用性,提取共性
 * 这个方法谁来调用的?
 * SpringMVC中的前端控制器进行调用
 * 和调用Controller层方法处理用户请求是一样的
 * 
 * @author private
 *
 */
//@ControllerAdvice
//@ResponseBody
@RestControllerAdvice//-->它等于 @ControllerAdvice + @ResponseBody
public class GlobalExceptionHandler {
	
	@ExceptionHandler(ShiroException.class)
	public JsonResult doHandlerShiroException(ShiroException e) {
		JsonResult r = new JsonResult();
		r.setState(0);
		if(e instanceof UnknownAccountException) {
			r.setMessage("账户不存在");
		}else if(e instanceof LockedAccountException) {
			r.setMessage("账户已被禁用");
		}else if(e instanceof IncorrectCredentialsException) {
			r.setMessage("密码不正确");
		}else if(e instanceof AuthorizationException) {
			r.setMessage("没有此操作权限");
		}else {
			r.setMessage("系统维护中");
		}
		return r;
	}
	
	//这个注解描述的方法为一个异常处理方法,注解中定义的异常类型为此方法的异常处理类型和子类类型异常
	//在异常处理方法中,通常会定义一个异常参数来接收异常对象
//	@ExceptionHandler({RuntimeException.class,ServiceException.class})//一个方法处理多个异常
	@ExceptionHandler(RuntimeException.class)
	public JsonResult doHandlerRuntimeException(RuntimeException e) {
		System.out.println("异常处理方法执行了!"+e.getMessage());
		return new JsonResult(e);
	}
}
